﻿using SkiaSharp;

namespace VueAdminService.Utils
{
	/// <summary>
	/// 验证码相关
	/// </summary>
	public class VerifyCodeUtil
	{
		/// <summary>
		/// 生成指定长度的随机字符串
		/// (包含数字+大小写字母,不包含特殊符号)
		/// </summary>
		/// <param name="length">随机字符串长度</param>
		/// <returns>字符串长度，包含数字t,包含符号f，包含小写字母t，包含大写字母t</returns>
		public static string GenerateVerifyCode(int length)
		{
			return GenerateVerifyCode(length, true, false, true, true);//字符串长度，包含数字t,包含符号f，包含小写字母t，包含大写字母t
		}
		/// <summary>
		/// 生成指定长度的随机字符串
		/// </summary>
		/// <param name="intLength">随机字符串长度</param>
		/// <param name="booNumber">生成的字符串中是否包含数字</param>
		/// <param name="booSign">生成的字符串中是否包含符号</param>
		/// <param name="booSmallword">生成的字符串中是否包含小写字母</param>
		/// <param name="booBigword">生成的字符串中是否包含大写字母</param>
		/// <returns></returns>
		private static string GenerateVerifyCode(int intLength, bool booNumber, bool booSign, bool booSmallword, bool booBigword)
		{
			//定义  
			Random ranA = new Random();
			int intResultRound = 0;
			int intA = 0;
			string strB = "";

			while (intResultRound < intLength)
			{
				//生成随机数A，表示生成类型  
				//1=数字，2=符号，3=小写字母，4=大写字母  

				intA = ranA.Next(1, 5);

				//如果随机数A=1，则运行生成数字  
				//生成随机数A，范围在0-10  
				//把随机数A，转成字符  
				//生成完，位数+1，字符串累加，结束本次循环  

				if (intA == 1 && booNumber)
				{
					intA = ranA.Next(0, 10);
					strB = intA.ToString() + strB;
					intResultRound = intResultRound + 1;
					continue;
				}

				//如果随机数A=2，则运行生成符号  
				//生成随机数A，表示生成值域  
				//1：33-47值域，2：58-64值域，3：91-96值域，4：123-126值域  

				if (intA == 2 && booSign == true)
				{
					intA = ranA.Next(1, 5);

					//如果A=1  
					//生成随机数A，33-47的Ascii码  
					//把随机数A，转成字符  
					//生成完，位数+1，字符串累加，结束本次循环  

					if (intA == 1)
					{
						intA = ranA.Next(33, 48);
						strB = ((char)intA).ToString() + strB;
						intResultRound = intResultRound + 1;
						continue;
					}

					//如果A=2  
					//生成随机数A，58-64的Ascii码  
					//把随机数A，转成字符  
					//生成完，位数+1，字符串累加，结束本次循环  

					if (intA == 2)
					{
						intA = ranA.Next(58, 65);
						strB = ((char)intA).ToString() + strB;
						intResultRound = intResultRound + 1;
						continue;
					}

					//如果A=3  
					//生成随机数A，91-96的Ascii码  
					//把随机数A，转成字符  
					//生成完，位数+1，字符串累加，结束本次循环  

					if (intA == 3)
					{
						intA = ranA.Next(91, 97);
						strB = ((char)intA).ToString() + strB;
						intResultRound = intResultRound + 1;
						continue;
					}

					//如果A=4  
					//生成随机数A，123-126的Ascii码  
					//把随机数A，转成字符  
					//生成完，位数+1，字符串累加，结束本次循环  

					if (intA == 4)
					{
						intA = ranA.Next(123, 127);
						strB = ((char)intA).ToString() + strB;
						intResultRound = intResultRound + 1;
						continue;
					}

				}

				//如果随机数A=3，则运行生成小写字母  
				//生成随机数A，范围在97-122  
				//把随机数A，转成字符  
				//生成完，位数+1，字符串累加，结束本次循环  

				if (intA == 3 && booSmallword == true)
				{
					intA = ranA.Next(97, 123);
					strB = ((char)intA).ToString() + strB;
					intResultRound = intResultRound + 1;
					continue;
				}

				//如果随机数A=4，则运行生成大写字母  
				//生成随机数A，范围在65-90  
				//把随机数A，转成字符  
				//生成完，位数+1，字符串累加，结束本次循环  

				if (intA == 4 && booBigword == true)
				{
					intA = ranA.Next(65, 89);
					strB = ((char)intA).ToString() + strB;
					intResultRound = intResultRound + 1;
					continue;
				}
			}
			return strB;

		}

		/// <summary>
		/// 获取图像数字验证码
		/// </summary>
		/// <param name="text">验证码内容</param>
		/// <returns></returns>
		public static byte[] GenerateImage(string text)
		{			
			int width = 75;
			int height = 40;

			Random random = new();
			//创建bitmap位图
			using SKBitmap image = new(width, height, SKColorType.Bgra8888, SKAlphaType.Premul);
			//创建画笔
			using SKCanvas canvas = new(image);
			//填充背景颜色为白色
			canvas.DrawColor(SKColors.White);
			//颜色列表
			SKColor[] colors = { SKColors.Black, SKColors.Red, SKColors.Blue, SKColors.Green, SKColors.Orange, SKColors.Brown, SKColors.DarkBlue };
			//画图片的背景噪音线
			for (int i = 0; i < 20; i++)
			{
				using SKPaint drawStyle = new();
				drawStyle.Color = colors[random.Next(colors.Length)];
				canvas.DrawLine(random.Next(0, width), random.Next(0, height), random.Next(0, width), random.Next(0, height), drawStyle);
			}
			//将文字写到画布上
			using (SKPaint drawStyle = new())
			{
				var realWidth = width - 10;//左右边距10,解决最后一个可能显示不全
				drawStyle.TextSize = height;
				drawStyle.StrokeWidth = 1;
				float emHeight = height - (float)height * (float)0.14;
				float emWidth = ((float)realWidth / text.Length) - ((float)realWidth * (float)0.13) + 5;
				for (int i = 0; i < text.Length; i++)
				{
					drawStyle.Color = colors[random.Next(colors.Length)];

					var jg = (realWidth - (emWidth * text.Length)) / text.Length - 1;
					//画在画板上
					canvas.DrawText(text[i].ToString(), emWidth * i + jg, emHeight, drawStyle);
				}
			}

			//画图片的前景噪音点
			for (int i = 0; i < 100; i++)
			{
				image.SetPixel(random.Next(0, width), random.Next(0, height), colors[random.Next(colors.Length)]);
			}

			using var img = SKImage.FromBitmap(image);
			using SKData p = img.Encode(SKEncodedImageFormat.Png, 100);
			return p.ToArray();
		}
	}
}
